package com.glacier.yuyuan.modules.admin.sys.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.glacier.common.core.constant.CommonConstant;
import com.glacier.common.support.service.impl.TreeServiceImpl;
import com.glacier.yuyuan.modules.admin.sys.domain.Office;
import com.glacier.yuyuan.modules.admin.sys.mapper.OfficeMapper;
import com.glacier.yuyuan.modules.admin.sys.mapper.RoleOfficeMapper;
import com.glacier.yuyuan.modules.admin.sys.service.OfficeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;

/**
 * date 2022-11-10 12:48
 * 组织机构业务层
 *
 * @author glacier
 * @version 1.0
 */
@Transactional(readOnly = true)
@Service
public class OfficeServiceImpl extends TreeServiceImpl<OfficeMapper, Office> implements OfficeService {

    private RoleOfficeMapper roleOfficeMapper;

    protected OfficeServiceImpl() {
        super(OfficeMapper.class);
    }

    @Autowired
    public void setRoleOfficeMapper(RoleOfficeMapper roleOfficeMapper) {
        this.roleOfficeMapper = roleOfficeMapper;
    }

    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int save(Office entity) {
        int update = super.save(entity);
        updateSelfAndChildrenParents(entity);
        return update;
    }

    /**
     * 更新父级ids
     *
     * @param entity 实体
     * @return 影响的行数
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateParents(Office entity) {
        if (StrUtil.isBlank(entity.getId()) ||
            StrUtil.isBlank(entity.getParentId())) {
            return 0;
        }
        fillParentIds(mapper, entity);
        return mapper.updateParents(entity);
    }


    /**
     * 更新父级ids
     *
     * @param entity 实体
     * @return 影响的行数
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateSelfAndChildrenParents(Office entity) {
        List<String> allChildrenIds = mapper.findAllChildrenIds(List.of(entity.getId()));
        List<Office> officeList = mapper.findListByIds(allChildrenIds);
        return mybatisBatchUtils.batchUpdateOrInsert(officeList, OfficeMapper.class,
            (items, mapper1) -> {
                for (Office item : items) {
                    fillParentIds(mapper1, item);
                }
                return items;
            },
            (item, mapper1) -> mapper1.updateParents(item));
    }

    /**
     * 删除回调
     *
     * @param idList
     */
    @Override
    protected <ID extends Serializable> void afterBatchDelete(final List<ID> idList) {
        if (!idList.isEmpty()) {
            // 删除机构和角色关系
            roleOfficeMapper.deleteByOfficeIds(idList);
        }
    }

    /**
     * 填充 parentIds
     *
     * @param mapper 采用的 mapper
     * @param entity 实体
     */
    private void fillParentIds(OfficeMapper mapper, final Office entity) {
        List<String> parentIds = mapper.findAllParentIds(entity.getId());
        // 剔除自身
        CollectionUtil.removeAny(parentIds, entity.getId());
        // 首尾加上 半角逗号
        entity.setParentIds(
            StrUtil.concat(false,
                CommonConstant.HALF_CORNER_COMMA,
                CollectionUtil.join(parentIds, CommonConstant.HALF_CORNER_COMMA),
                CommonConstant.HALF_CORNER_COMMA)
        );
    }
}
